package edu.ccut.saturn.component.utils;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

import edu.ccut.saturn.core.impl.HostActivator;

/**
 * 类加载工具类
 * 
 * @author LeslieGu
 * 
 */
public abstract class LoaderUtils {

	/**
	 * 根据类全名，读取该类的Class对象。这里首先通过Bundle的类加载器读取Class对象，<P>
	 * 如果失败通过LoaderUtils类所在的类加载器读取Class对象，<P>
	 * 如果失败通过当前线程的类加载器读取Class对象,<p>
	 * 如果失败，抛出ClassNotFoundException
	 * 
	 * @param bundle 当前Bundle对象
	 * @param className 类全名
	 * @return Class对象
	 * 
	 * @throws ClassNotFoundException
	 */
	public static Class<?> loadClass(Bundle bundle, String className) {

		Class<?> classType = null;

		try {
			classType = bundle.loadClass(className);
		} catch (Exception e) {
			// 被注释的代码执行的功能是：在一个bundle内加载其它bundle内的类，是通过一个字符串类型的类名加载的。
			// 但这个功能在websphere6.1下无法使用，抛出NoSuchMethodException。
			// try {
			// Bundle[] bundles = bundle.getBundleContext().getBundles();
			//				
			// for (Bundle bundleItem : bundles) {
			//				
			// try {
			// classType = bundleItem.loadClass(className);
			//				
			// if (classType != null) {
			// break;
			// }
			//				
			// } catch (Exception exception) {
			//				
			// }
			// }
			//				
			// if (classType == null) {
			// throw new Exception();
			// }
			//
			// } catch (Exception e0) {
			try {
				classType = LoaderUtils.class.getClassLoader().loadClass(
						className);

			} catch (Exception e1) {
				try {
					classType = Thread.currentThread().getContextClassLoader()
							.loadClass(className);
				} catch (ClassNotFoundException e2) {
					//e2.printStackTrace();
				}
			}
		} 
		
		return classType;
	}
	
	public static Class<?> loadClass(String className) {
		BundleContext bundleContext = HostActivator.getInstance().getBundleContext();
		
		if (bundleContext != null) {
			Bundle[] bundles = bundleContext.getBundles();
			
			Class<?> classType = null;
			for (Bundle bundle : bundles) {
				classType = loadClass(bundle, className);
				
				if (classType != null) {
					return classType;
				}
			}
		}
		
		return null;
	}
	
	public static ClassLoader getBundleClassLoader() {
		return new ClassLoader() {

			@Override
			public Class<?> loadClass(String name)
					throws ClassNotFoundException {
				
				Class<?> classType = LoaderUtils.loadClass(name);
				
				if (classType != null) {
					return classType;
				}
				
				return super.loadClass(name);
			}
		};
	}
}
